package ebcs.plat.icop.connect;

import java.net.MalformedURLException;
import java.rmi.RemoteException;

import javax.xml.rpc.ServiceException;

import org.apache.log4j.Logger;

import ebcs.plat.trans.base.KTransResponse;
import jplat.core.net.webservice.JWebServieClient;
import jplat.core.trans.JTransContext;
import jplat.tools.coder.xml.JNXmlParser;
import jplat.tools.coder.xml.PTXmlIndex;
import jplat.tools.config.JSystemConfig;
import jplat.tools.string.DateUtil;
import jplat.tools.string.StringUtil;

public class ICOPConnector
{
	//请求地址
	private static String url = JSystemConfig.getInstance().getString("icop.url");
//	private static String url = "http://162.16.1.137:43294/icop/services/JTService?wsdl";
	
	private static String xmlCharsetMark = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
	
	//操作类型.
//	private static String opName = JSystemConfig.getInstance().getString("icop.opName");
	private static String opName = "request";
	
	//E钱庄默认接入渠道号
	private static String __CHNL_ID_EBK = "104";
	
	private static Logger logger = Logger.getLogger(ICOPConnector.class);
	
	/* 外部可设置的请求头信息 **/
	public static String khUUID = "__H_UUID";				//UUID
	public static String khSEQNO = "__H_SEQNO";			//流水
	public static String khCHANNEL_ID = "__H_CHANNEL_ID";	//渠道
	public static String khBRANCH_ID = "__H_BRANCH_ID";	//机构号
	public static String khOPER_ID = "__H_OPER_ID";		//操作员号
	public static String khENC_TYPE = "__H_ENC_TYPE";		//加密类型或者密码类型.
	public static String khTERM_NO = "__H_TERM_NO";		//终端类型
	
	public static boolean sendICOPMessage( JTransContext context )
	{
		String retXml = "";
		
		try
		{
			retXml = JWebServieClient.sendMessage(url, opName, packICOPXML(context) );
		}
		catch (RemoteException | MalformedURLException | ServiceException e)
		{
			// TODO Auto-generated catch block
			context.fail(KTransResponse.CD_ICOP_CONNECT_FAIL, KTransResponse.MSG_ICOP_CONNECT_FAIL );
			e.printStackTrace();
			return false;
		}

		//判空.
		if ( StringUtil.isEmpty(retXml) )
		{
			context.fail(KTransResponse.CD_ICOP_EMPTY_RETBODY, KTransResponse.MSG_ICOP_EMPTY_RETBODY );
			return false;
		}
		
		//设置返回数据.
		context.setRetPack(retXml);
		
		//解包
		if( !unpackICOPXML(context) )
		{
			logger.error("渠道交易失败.");
			return false;
		}
		
		return true;
	}
	
	/**
	 * 组成请求头部文件.
	 * @author zhangcq
	 * @date Nov 23, 2016
	 * @comment 
	 * @param context
	 * @return
	 */
	private static ICOPReqHeaderV1 buildRequestHead( JTransContext context )
	{
		ICOPReqHeaderV1 head = new ICOPReqHeaderV1();
		head.setServiceCode(context.getTransCode());				//交易码 非空
		head.setExternalReference(context.getString(ICOPConnector.khSEQNO));		//交易流水 非空.
		head.setVersion("1.0");

		head.setRequestTime( DateUtil.todayStr("yyyyMMddHHmmssSSS"));
		head.setTradeDate(DateUtil.todayStr("yyyyMMdd"));

		head.setUuid(StringUtil.getDefString(context.getString(ICOPConnector.khUUID), ""));
		head.setChannelId(StringUtil.getDefString(context.getString(ICOPConnector.khCHANNEL_ID), __CHNL_ID_EBK));
		head.setEncrypt(StringUtil.getDefString(context.getString(ICOPConnector.khENC_TYPE), ""));

		head.setTermNo(StringUtil.getDefString(context.getString(ICOPConnector.khTERM_NO), ""));
		head.setRequestBranchCode(StringUtil.getDefString(context.getString(ICOPConnector.khBRANCH_ID), ""));
		head.setRequestOperatorId(StringUtil.getDefString(context.getString(ICOPConnector.khOPER_ID), ""));

		return head;
	}
	
	/**
	 * 拼接包.
	 * @author zhangcq
	 * @date Nov 23, 2016
	 * @comment 
	 * @param context
	 * @return
	 */
	private static String packICOPXML( JTransContext context )
	{
		StringBuilder builder = new StringBuilder(3000);
		builder.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
				.append("<Service>")
				.append(JNXmlParser.obj2Xml(buildRequestHead(context)))
				.append("<Body>")
				.append(JNXmlParser.obj2Xml(context.getReqBody()))
				.append("</Body></Service>");
		
		return builder.toString();
	}
	
	/***
	 * 渠道解包.
	 * @author zhangcq
	 * @date Nov 23, 2016
	 * @comment 
	 * @param context
	 * @return
	 */
	private static boolean unpackICOPXML( JTransContext context )
	{
		//解析请求头.
		PTXmlIndex xmlInfo = JNXmlParser.parseDataBetweenMark(context.getRetPack(), "<Header>", "</Header>", true);
		
		if ( xmlInfo.error )
		{
			logger.error("解析请求头失败.XML::"+context.getRetPack());
			context.fail(KTransResponse.CD_ICOP_PACK_ERR, KTransResponse.MSG_ICOP_PACK_ERR);
			return false;
		}
		
		//渠道返回失败.
		ICOPRspHeaderV1 response = (ICOPRspHeaderV1)JNXmlParser.xml2Obj(xmlCharsetMark+xmlInfo.content, ICOPRspHeaderV1.class);
		if (  (response.getResonse() == null)
				|| !StringUtil.isEqual( response.getResonse().getReturnCode(), "00000000","0000", "000000" ) )
		{
			logger.error("__ICOP_FAIL__:"+context.getTransCode()+":"+response.getResonse()==null?"呃...系统未知错误":""+response.getResonse().getReturnMessage());
			context.fail(KTransResponse.CD_ICOP_TRANS_FAIL, response.getResonse().getReturnMessage()+"" );
			return false;
		}
		
		//解析请求体.
		PTXmlIndex bodyInfo = JNXmlParser.parseDataBetweenMark( context.getRetPack().substring(xmlInfo.index), "<Body>", "</Body>", false );
		if ( bodyInfo.error )
		{
			context.fail(KTransResponse.CD_ICOP_PACK_ERR, KTransResponse.MSG_ICOP_PACK_ERR);
			return false;
		}
		
		context.setRetPack(null);
		context.setRspBodyStr(xmlCharsetMark+bodyInfo.content);
		
		return true;
	}
	
	public static void main(String args[])
	{
		JTransContext ctx = new JTransContext("");
		ctx.putValue(khSEQNO, "9874kjkdfg8u9ojlkdjg");
		ctx.setTransCode("WDCO9987");
		
		ICOPRspInfo rspInfo = new ICOPRspInfo();
		rspInfo.setReturnCode("000_999");
		rspInfo.setReturnMessage("success___");
		
		ctx.setReqBody(rspInfo);
		
		System.out.println(packICOPXML(ctx));
	}
}
